﻿using System;
using System.Collections.Generic;

namespace ExcelConverter
{
    public static class ConverterUtils
    {
        public static (bool success, int intValue) ToInt(string str)
        {
            //移除多余符号
            str = str.Replace("_", "");
            if (string.IsNullOrEmpty(str))
            {
                return (true, 0);
            }
            if (double.TryParse(str, out var value))
            {
                return (true, ToInt(value));
            }
            return (false, 0);
        }
        public static (bool success, ulong ulongValue) ToUlong(string str)
        {
            //移除多余符号
            str = str.Replace("_", "");
            if (string.IsNullOrEmpty(str))
            {
                return (true, 0);
            }
            if (double.TryParse(str, out var value))
            {
                return (true, ToUlong(value));
            }
            return (false, 0);
        }
        public static int ToInt(double doub)
        {
            return (int) Math.Round(doub);
        }
        public static ulong ToUlong(double doub)
        {
            return (ulong) Math.Round(doub);
        }

        
        public enum EWriteResult
        {
            Success,
            CouldNotFoundVarDefined,
            IncorrectFormatForInt,
            IncorrectFormatForDouble,
            IncorrectFormatForBool,
            ContainsEmptyStr,
        }
        public static (EWriteResult result, string arg) WriteIntArray(CodeWriter codeWriter, string cellValue, bool isDefined, Dictionary<string, string> defineMap)
        {
            codeWriter.WriteArrayStart();
            //可以使用多种符号作为分隔符
            var strings = cellValue.Split(Converter.COMMON_ARR_SPLIT_CHARS);
            for (var i = 0; i < strings.Length; i++)
            {
                var str = strings[i];
                if (string.IsNullOrEmpty(str)) 
                {
                    if (strings.Length > 1) return (EWriteResult.ContainsEmptyStr, null);
                    codeWriter.Write(default(int));
                    continue;
                }
                //包含加法
                if (isDefined && str.Contains("&"))
                {
                    var addValues = cellValue.Split('&');
                    var intValue = 0;
                    for (var j = 0; j < addValues.Length; j++)
                    {
                        var addValue = addValues[j];
                        if (!defineMap.ContainsKey(addValue))
                        {
                            return (EWriteResult.CouldNotFoundVarDefined, addValue);
                        }
                        var defineValue = defineMap[addValue];
                        var result = ToInt(defineValue);
                        if (result.success)
                        {
                            intValue += result.intValue;
                        }
                        else
                        {
                            return (EWriteResult.IncorrectFormatForInt, defineValue);
                        }
                    }
                    codeWriter.Write(intValue);
                }
                else
                {
                    if (isDefined)
                    {
                        if (defineMap.ContainsKey(str))
                        {
                            str = defineMap[str];
                        }
                    }
                    var result = ToInt(str);
                    if (result.success)
                    {
                        codeWriter.Write(result.intValue);
                    }
                    else
                    {
                        return (EWriteResult.CouldNotFoundVarDefined, str);
                    }
                }
            }
            codeWriter.WriteArrayEnd();
            return (EWriteResult.Success, null);
        }
        public static (EWriteResult result, string arg) WriteUlongArray(CodeWriter codeWriter, string cellValue)
        {
            codeWriter.WriteArrayStart();
            //可以使用多种符号作为分隔符
            var strings = cellValue.Split(Converter.COMMON_ARR_SPLIT_CHARS);
            for (var i = 0; i < strings.Length; i++)
            {
                var str = strings[i];
                if (string.IsNullOrEmpty(str)) 
                {
                    if (strings.Length > 1) return (EWriteResult.ContainsEmptyStr, null);
                    codeWriter.Write(default(ulong));
                    continue;
                }
                var result = ToUlong(str);
                if (result.success)
                {
                    codeWriter.Write(result.ulongValue);
                }
                else
                {
                    return (EWriteResult.CouldNotFoundVarDefined, str);
                }
            }
            codeWriter.WriteArrayEnd();
            return (EWriteResult.Success, null);
        }
        public static (EWriteResult result, string arg) WriteDoubleArray(CodeWriter codeWriter, string cellValue, bool isDefined, Dictionary<string, string> defineMap)
        {
            codeWriter.WriteArrayStart();
            var strings = cellValue.Split(Converter.COMMON_ARR_SPLIT_CHARS);
            for (var i = 0; i < strings.Length; i++)
            {
                var str = strings[i];
                if (string.IsNullOrEmpty(str)) 
                {
                    if (strings.Length > 1) return (EWriteResult.ContainsEmptyStr, null);
                    codeWriter.Write(default(double));
                    continue;
                }
                if (isDefined)
                {
                    if (defineMap.ContainsKey(str))
                    {
                        str = defineMap[str];
                    }
                }
                if (double.TryParse(str, out var value))
                {
                    codeWriter.Write(value);
                }
                else
                {
                    return (EWriteResult.IncorrectFormatForDouble, str);
                }
            }
            codeWriter.WriteArrayEnd();
            return (EWriteResult.Success, null);
        }
        public static (EWriteResult result, string arg) WriteBoolArray(CodeWriter codeWriter, string cellValue, bool isDefined, Dictionary<string, string> defineMap)
        {
            codeWriter.WriteArrayStart();
            var strings = cellValue.Split(Converter.COMMON_ARR_SPLIT_CHARS);
            for (var i = 0; i < strings.Length; i++)
            {
                var str = strings[i];
                if (string.IsNullOrEmpty(str)) 
                {
                    if (strings.Length > 1) return (EWriteResult.ContainsEmptyStr, null);
                    codeWriter.Write(default(bool));
                    continue;
                }
                if (isDefined)
                {
                    if (defineMap.ContainsKey(str))
                    {
                        str = defineMap[str];
                    }
                }
                if (double.TryParse(str, out var value))
                {
                    codeWriter.Write(value > 0.5d);
                }
                else
                {
                    return (EWriteResult.IncorrectFormatForBool, str);
                }
            }
            codeWriter.WriteArrayEnd();
            return (EWriteResult.Success, null);
        }
        public static (EWriteResult result, string arg) WriteStringArray(CodeWriter codeWriter, string cellValue, bool isDefined, Dictionary<string, string> defineMap)
        {
            codeWriter.WriteArrayStart();
            var strings = cellValue.Split(Converter.STRING_ARR_SPLIT_CHARS);
            for (var i = 0; i < strings.Length; i++)
            {
                var str = strings[i].Trim('\n');
                if (isDefined)
                {
                    if (defineMap.ContainsKey(str))
                    {
                        str = defineMap[str];
                    }
                }
                codeWriter.Write(str);
            }
            codeWriter.WriteArrayEnd();
            return (EWriteResult.Success, null);
        }
        
        /// <summary>
        /// DateTime 转 秒级时间戳
        /// </summary>
        public static int GetTimeStampByUTCTime(DateTime time, int offset)
        {
            var dtStart = new DateTime(1970, 1, 1, 0, 0, 0);
            dtStart = dtStart.AddHours(offset);
            var toNow = time - dtStart;
            return (int) toNow.TotalSeconds;
        }
    }
}